 

package com.zdkj.subway.rca.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.rca.dto.in.UserDto;
import com.zdkj.subway.rca.entity.*;
import com.zdkj.subway.rca.service.*;
import com.zdkj.subway.rca.util.MyDateUtil;
import com.zdkj.subway.rca.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * BOM小额支付平台数据汇总表
 *
 * @author stw
 * @date 2020-10-27 20:28:52
 */
@RestController
@AllArgsConstructor
@RequestMapping("/swckbomsmallpayment" )
@Api(value = "swckbomsmallpayment", tags = "非现金收入审核-BOM小额支付平台数据汇总表管理")
public class SwCkBomSmallPaymentController {

    private final SwCkBomSmallPaymentService swCkBomSmallPaymentService;

    @Autowired
    private SwCkBomSmallPaymentWechatService swCkBomSmallPaymentWechatService;
    @Autowired
    private SwCkBomSmallPaymentWechatTmpService swCkBomSmallPaymentWechatTmpService;

    @Autowired
    private SwCkBomSmallPaymentAlipayService swCkBomSmallPaymentAlipayService;
    @Autowired
    private SwCkBomSmallPaymentAlipayTmpService swCkBomSmallPaymentAlipayTmpService;
    @Autowired
    private SwAuMarketingTicketService swAuMarketingTicketService;
    /**
     * 分页查询
     * @param page 分页对象
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page" )
    public R getSwCkBomSmallPaymentPage(Page page, String startDate, String endDate) {
        //SwCkBomSmallPayment swCkBomSmallPayment = new SwCkBomSmallPayment();
        IPage<SwCkBomSmallPayment>  list = swCkBomSmallPaymentService.selectPage(page,startDate,endDate);
        return R.ok(list);
        //return R.ok(swCkBomSmallPaymentService.page(page, Wrappers.query(swCkBomSmallPayment).lambda().ge(StringUtils.isNotEmpty(startDate), SwCkBomSmallPayment::getTradeDate, startDate).le( StringUtils.isNotEmpty(endDate), SwCkBomSmallPayment::getTradeDate, endDate).orderByDesc(SwCkBomSmallPayment::getTradeDate)));
    }


    /**
     * 导出模板
     * @param
     * @return
     * @throws IOException
     */
    @ApiOperation(value = "导出模板,verfiyConfirmFlag： 1,微信；2，支付宝", notes = "导出模板,verfiyConfirmFlag： 1,微信；2，支付宝")
    @GetMapping("/exportTamplates")
    @PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public void exportTamplates(String verfiyConfirmFlag, HttpServletResponse response) {
        swCkBomSmallPaymentService.exportTamplates(verfiyConfirmFlag,response);
    }

    /**
     * 批量导入对账确认表
     * @param file
     * @param verfiyConfirmFlag
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "批量导入对账确认表,verfiyConfirmFlag： 1,微信；2，支付宝", notes = "批量导入对账确认表,verfiyConfirmFlag： 1,微信；2，支付宝")
    @SysLog("批量导入对账确认表")
    @PostMapping(value = "/saveBatch",  headers = "content-type=multipart/form-data")
    @PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public R saveBatch(@RequestParam(value = "file") MultipartFile file, @RequestParam String verfiyConfirmFlag) throws Exception {
        return R.ok((Object)this.swCkBomSmallPaymentService.saveBatchWithExcel(file,verfiyConfirmFlag));
    }

    /**
     * 导入后确认表列表查询
     * @return
     */
    @ApiOperation(value = "导入后确认表列表查询", notes = "导入后确认表列表查询")
    @GetMapping("/listConfirmTable" )
    @PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public R getSwCkBomSmallPaymentConfirmTableList() {
        List<Map<String,String>> list = swCkBomSmallPaymentService.getSwCkBomSmallPaymentConfirmTableList();
        return R.ok(list);
    }


    /**
     * 各个确认表导入预处理分页查询
     * @return
     */
    @ApiOperation(value = "各个确认表导入预处理分页查询", notes = "各个确认表导入预处理分页查询")
    @GetMapping("/listPreprocessing" )
    @PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public R listPreprocessing(Page page, String verfiyConfirmFlag) {
        PigxUser user = SecurityUtils.getUser();
        if("1".equals(verfiyConfirmFlag)) { //BOM小额支付平台数据审核-微信
            SwCkBomSmallPaymentWechatTmp swCkBomSmallPaymentWechatTmp = new  SwCkBomSmallPaymentWechatTmp();
            swCkBomSmallPaymentWechatTmp.setCreatorId(user.getId());
            return R.ok(swCkBomSmallPaymentWechatTmpService.page(page,Wrappers.query(swCkBomSmallPaymentWechatTmp)));
        } else if("2".equals(verfiyConfirmFlag)) { //BOM小额支付平台数据审核-支付宝
            SwCkBomSmallPaymentAlipayTmp swCkBomSmallPaymentAlipayTmp = new  SwCkBomSmallPaymentAlipayTmp();
            swCkBomSmallPaymentAlipayTmp.setCreatorId(user.getId());
            return R.ok(swCkBomSmallPaymentAlipayTmpService.page(page,Wrappers.query(swCkBomSmallPaymentAlipayTmp)));
        } else {
            return R.ok();
        }

    }
    /**
     * 各个确认表导入预处理确认
     * @param verfiyConfirmFlag
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "各个确认表导入预处理确认", notes = "各个确认表导入预处理确认")
    //@SysLog("确认表导入预处理确认")
    @GetMapping({ "/saveBatchOk" })
    //@PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public R saveBatchOk(@RequestParam String verfiyConfirmFlag) throws Exception {
        PigxUser pigxUser = SecurityUtils.getUser();
        UserDto user = new UserDto();
        if(pigxUser == null){
            user = UserUtil.userDto();
        }else {
            user = UserUtil.pigxUser();
        }
        if("1".equals(verfiyConfirmFlag)) {
            this.swCkBomSmallPaymentWechatTmpService.saveBatchWithExcelOk(user.getId());

        } else if("2".equals(verfiyConfirmFlag)) {
            this.swCkBomSmallPaymentAlipayTmpService.saveBatchWithExcelOk(user.getId());

        }  else {
            return R.ok(false);
        }

        return R.ok(true);
    }
    /**
     * 各个确认表导入预处理取消
     * @param verfiyConfirmFlag
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "各个确认表导入预处理取消", notes = "各个确认表导入预处理取消")
    @SysLog("确认表导入预处理取消")
    @GetMapping({ "/saveBatchCancel" })
    @PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public R saveBatchCancel(@RequestParam String verfiyConfirmFlag) throws Exception {
        PigxUser user = SecurityUtils.getUser();
        if("1".equals(verfiyConfirmFlag)) {
            this.swCkBomSmallPaymentWechatTmpService.saveBatchWithExcelCancel(user.getId());

        } else if("2".equals(verfiyConfirmFlag)) {
            this.swCkBomSmallPaymentAlipayTmpService.saveBatchWithExcelCancel(user.getId());

        }  else {
            return R.ok(false);
        }

        return R.ok(true);
    }

    /**
     * 各个确认表分页预览
     * @return
     */
    @ApiOperation(value = "各个确认表汾分页预览", notes = "各个确认表分页预览")
    @GetMapping("/listPreview" )
    @PreAuthorize("@pms.hasPermission('sw_ck_bom_small_payment_import')")
    public R listPreview(Page page, String tradeDate,String verfiyConfirmFlag) throws Exception {
        if(StringUtils.isEmpty(tradeDate) || StringUtils.isEmpty(verfiyConfirmFlag)){
            return R.ok(CommonConstants.FAIL);
        }

        if("1".equals(verfiyConfirmFlag)) {
            SwCkBomSmallPaymentWechat swCkBomSmallPaymentWechat = new SwCkBomSmallPaymentWechat();
            return R.ok(swCkBomSmallPaymentWechatService.page(page,Wrappers.query(swCkBomSmallPaymentWechat).lambda().eq(SwCkBomSmallPaymentWechat::getTradeDate,tradeDate)));
        } else if("2".equals(verfiyConfirmFlag)) {
            SwCkBomSmallPaymentAlipay swCkbomSmallPaymentAlipay = new SwCkBomSmallPaymentAlipay();
            return R.ok(swCkBomSmallPaymentAlipayService.page(page,Wrappers.query(swCkbomSmallPaymentAlipay).lambda().eq(SwCkBomSmallPaymentAlipay::getTradeDate,tradeDate)));
        } else {
            return R.ok();
        }

    }

    /**
     * BOM小额支付平台和营销车票生成库存对比
     * @param startDate   开始日期：yyyy-MM-dd
     * @param endDate     结束日期：yyyy-MM-dd
     * @return
     */
    @ApiOperation(value = "BOM小额支付平台和营销车票生成库存对比", notes = "BOM小额支付平台和营销车票生成库存对比")
    @GetMapping("/getGenerateInventoryComparison")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "startDate", value = "开始日期：yyyy-MM-dd", dataTypeClass = String.class),
                    @ApiImplicitParam(name = "endDate", value = "结束日期：yyyy-MM-dd", dataTypeClass = String.class),
					@ApiImplicitParam(name = "lineCodes", value = "线路编号", dataTypeClass = String.class)
            }
    )
    public R getGenerateInventoryComparison(String startDate, String endDate,String lineCodes) {
		String lineCode = lineCodes;
		//System.out.println("进入生成==-"+lineCode);
        boolean isDateCondition = StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate);
        if(isDateCondition) {
            LocalDate startDateLocalDate = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            LocalDate endDateLocalDate = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            //BOM小额支付平台线路、站点、日期、数量、金额、票种的查询统计
            List<Map<String, Object>> swCkBomSmallCount = swCkBomSmallPaymentService.getSwCkBomSmallCount(startDateLocalDate, endDateLocalDate,lineCode);
            //车站录入的营销车票对应现金售卖方式的线路、站点、日期、票种、金额、数量
            List<Map<String, Object>> cashSale = swCkBomSmallPaymentService.getCashSale(startDateLocalDate, endDateLocalDate,lineCode);
            //车站录入的营销车票所有售卖方式的线路、站点、日期、票种、数量、金额（2021-10-27增加金额）
            List<Map<String, Object>> allSale = swCkBomSmallPaymentService.getAllSale(startDateLocalDate, endDateLocalDate,lineCode);

            ArrayList<SwAuMarketingTicket> arrayList = new ArrayList<>();
            for (Map<String, Object> bomsmall : swCkBomSmallCount) {

                String strLineCode = bomsmall.get("LINE_CODE").toString();
                String stationCode = bomsmall.get("STATION_CODE").toString();
                Date tradeDate = (Date) bomsmall.get("TRADE_DATE");
                String ticketType = bomsmall.get("TICKET_TYPE").toString();
                String ticketName = bomsmall.get("TICKET_NAME").toString();
                int amount = Integer.valueOf(bomsmall.get("AMOUNT").toString());//小额数量  bom小额支付平台的数量+营销车票现金售卖方式数量
                BigDecimal money = (BigDecimal) bomsmall.get("MONEY");//小额金额 +团购+转账金额
                int stockAmount = 0;//库存售卖数量
				BigDecimal stockMoney = new BigDecimal(0.00);//库存里的售卖金额
                int diffAmount = 0;//差异数量
				BigDecimal diffMoney = new BigDecimal(0.00);//小额与库存金额差异对比


                String tradeDateStr = MyDateUtil.dateToStr(tradeDate);
                for (Map<String, Object> cashsale : cashSale) {
                    //获取线路、站点、日期、票种、金额、数量
                    //根据小额支付平台里的线路、站点、日期、票种ticket_type进行匹配获取对应的金额和数量
                    String opertor_time = String.valueOf(cashsale.get("opertor_time"));
                    boolean isFirsttrue = strLineCode.equals(cashsale.get("line_code").toString())
                            && stationCode.equals(cashsale.get("station_code").toString())
                            && tradeDateStr.compareTo(opertor_time) == 0;
                    if(isFirsttrue){
                        if(!ticketType.equals("SRP")){
                            if (ticketType.equals(cashsale.get("ticket_type").toString())) {
                                //把数量和金额累加放在小额支付平台上
                                amount += Integer.valueOf(cashsale.get("amount").toString());
                                money = money.add((BigDecimal) cashsale.get("money"));
                                break;
                            }
                        }else {
                            if("SRP".equals(cashsale.get("ticket_type").toString()) || "ZLLJSRP".equals(cashsale.get("ticket_type").toString())){
                                //把数量和金额累加放在小额支付平台上
                                amount += Integer.valueOf(cashsale.get("amount").toString());
                                money = money.add((BigDecimal) cashsale.get("money"));
                            }
                        }
                    }
                }

                for (Map<String, Object> allsale : allSale) {
                    //获取线路、站点、日期、票种、数量、金额
                    //根据小额支付平台里的线路、站点、日期、票种ticket_type进行匹配获取对应的数量
                    String opertor_time = String.valueOf(allsale.get("opertor_time"));
                    boolean isFirsttrue = strLineCode.equals(allsale.get("line_code").toString())
                            && stationCode.equals(allsale.get("station_code").toString())
                            && tradeDateStr.compareTo(opertor_time) == 0;
                    if(isFirsttrue){
                        if(!ticketType.equals("SRP")){
                            if(ticketType.equals(allsale.get("ticket_type").toString())){
                                //把数量设置到库存上 开窗-关窗-废票，金额设置到库存金额
                                stockAmount = Integer.valueOf(allsale.get("amount").toString());
                                stockMoney = stockMoney.add((BigDecimal) allsale.get("money"));
                                break;
                            }
                        }else {
                            if("SRP".equals(allsale.get("ticket_type").toString()) || "ZLLJSRP".equals(allsale.get("ticket_type").toString())){
                                //把数量设置到库存上 开窗-关窗-废票，金额设置到库存金额
                                stockAmount = Integer.valueOf(allsale.get("amount").toString());
                                stockMoney = stockMoney.add((BigDecimal) allsale.get("money"));
                            }
                        }
                    }
                }

                //差异数量
                diffAmount = amount - stockAmount;
				//差异金额
                diffMoney = money.subtract(stockMoney);

                SwAuMarketingTicket swAuMarketingTicket = new SwAuMarketingTicket();
                swAuMarketingTicket.setLineCode(strLineCode);
                swAuMarketingTicket.setStationCode(stationCode);
                swAuMarketingTicket.setTradeTime(tradeDate);
                swAuMarketingTicket.setTicketType(ticketType);
                swAuMarketingTicket.setTicketName(ticketName);
                swAuMarketingTicket.setAmount(amount);
                swAuMarketingTicket.setStockAmount(stockAmount);
                swAuMarketingTicket.setMoney(money);
                swAuMarketingTicket.setStockMoney(stockMoney);
                swAuMarketingTicket.setDiffAmount(diffAmount);
				swAuMarketingTicket.setDiffMoney(diffMoney);
                swAuMarketingTicket.setConfirmStatus("0");
                swAuMarketingTicket.setCreateTime(new Date());
                arrayList.add(swAuMarketingTicket);

            }
            if(arrayList.size()>0) {
                
				
				//TODO 先根据日期范围以及线路查询
                if(StringUtils.isNotEmpty(lineCode)){
					 List<SwAuMarketingTicket> oldList = swAuMarketingTicketService.list(Wrappers.<SwAuMarketingTicket>lambdaQuery().eq(SwAuMarketingTicket::getLineCode,lineCode).between(SwAuMarketingTicket::getTradeTime, startDate, endDate));
					 swAuMarketingTicketService.remove(Wrappers.<SwAuMarketingTicket>lambdaQuery().eq(SwAuMarketingTicket::getLineCode,lineCode).between(SwAuMarketingTicket::getTradeTime, startDate, endDate));
	
				 //TODO 过滤出存在的数据并取id
                  List<SwAuMarketingTicket> collect = arrayList.stream().map(m -> {
                    oldList.stream().filter(m2 -> m.getTradeTime().compareTo(m2.getTradeTime()) == 0 && m.getLineCode().equals(m2.getLineCode()) && m.getStationCode().equals(m2.getStationCode()) && m.getTicketType().equals(m2.getTicketType()) && m.getTicketName().equals(m2.getTicketName()))
                            .forEach(s -> m.setId(s.getId()));
                    return m;
                }).collect(Collectors.toList());
                boolean isOk = swAuMarketingTicketService.saveOrUpdateBatch(arrayList);//TODO 根据线路+站点+日期+票种 判断是否生成过，如果生成过进行更新，否则插入
					//MP的字段默认更新策略
					if(isOk){
						List<Integer> integerList =
								collect.stream().filter(x -> x.getId() != null).map(m -> m.getId()).collect(Collectors.toList());
						swCkBomSmallPaymentService.updateBatch(integerList);
					}
					if (isOk) {
						swCkBomSmallPaymentWechatService.updateExecuteStatus(startDateLocalDate, endDateLocalDate,lineCode);
						swCkBomSmallPaymentAlipayService.updateExecuteStatus(startDateLocalDate, endDateLocalDate,lineCode);
					}
				//没有选择的具体线路
				}else{
                  List<SwAuMarketingTicket> oldList = swAuMarketingTicketService.list(Wrappers.<SwAuMarketingTicket>lambdaQuery().between(SwAuMarketingTicket::getTradeTime, startDate, endDate));
				  swAuMarketingTicketService.remove(Wrappers.<SwAuMarketingTicket>lambdaQuery().between(SwAuMarketingTicket::getTradeTime, startDate, endDate));
				   //TODO 过滤出存在的数据并取id
                  List<SwAuMarketingTicket> collect = arrayList.stream().map(m -> {
                    oldList.stream().filter(m2 -> m.getTradeTime().compareTo(m2.getTradeTime()) == 0 && m.getLineCode().equals(m2.getLineCode()) && m.getStationCode().equals(m2.getStationCode()) && m.getTicketType().equals(m2.getTicketType()) && m.getTicketName().equals(m2.getTicketName()))
                            .forEach(s -> m.setId(s.getId()));
                    return m;
                }).collect(Collectors.toList());
                boolean isOk = swAuMarketingTicketService.saveOrUpdateBatch(arrayList);//TODO 根据线路+站点+日期+票种 判断是否生成过，如果生成过进行更新，否则插入
					//MP的字段默认更新策略
					if(isOk){
						List<Integer> integerList =
								collect.stream().filter(x -> x.getId() != null).map(m -> m.getId()).collect(Collectors.toList());
						swCkBomSmallPaymentService.updateBatch(integerList);
					}
					if (isOk) {
						swCkBomSmallPaymentWechatService.updateExecuteStatus(startDateLocalDate, endDateLocalDate,lineCode);
						swCkBomSmallPaymentAlipayService.updateExecuteStatus(startDateLocalDate, endDateLocalDate,lineCode);
					}
				}
				
             
                return R.ok("生成成功！");
            }else {
                return R.failed("没有可生成的数据！");
            }
        }
        return R.ok();
    }
}
